using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System;
using System.Collections.Generic;
using static IQIGame.Onigao.GamePlay.UIN_CommonPetTips;

namespace IQIGame.Onigao.GamePlay
{
    public class UIN_HeroEquipSelectedPetInfo : UIBaseNode
    {
        #region Template Generate,don't modify
        protected class UIB_UIN_HeroEquipSelectedPetInfo
        {
            #region ObjectBinding Generate
            public UnityEngine.UI.ExLoopVerticalScrollRect loopVerticalScrollRect { protected set; get; }
            public UnityEngine.GameObject emptyScroll { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonSort { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonScreen { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonClose { protected set; get; }
            public UnityEngine.GameObject petTipsCompare { protected set; get; }
            public UnityEngine.GameObject petTipsCurrent { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnFilterClear { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonClosePetTips { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<UnityEngine.UI.ExLoopVerticalScrollRect>("loopVerticalScrollRect", out var __tbv0);
                this.loopVerticalScrollRect = __tbv0;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("emptyScroll", out var __tbv1);
                this.emptyScroll = __tbv1;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonSort", out var __tbv2);
                this.buttonSort = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonScreen", out var __tbv3);
                this.buttonScreen = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonClose", out var __tbv4);
                this.buttonClose = __tbv4;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("petTipsCompare", out var __tbv5);
                this.petTipsCompare = __tbv5;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("petTipsCurrent", out var __tbv6);
                this.petTipsCurrent = __tbv6;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnFilterClear", out var __tbv7);
                this.btnFilterClear = __tbv7;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonClosePetTips", out var __tbv8);
                this.buttonClosePetTips = __tbv8;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        #region fields
        private LoopScrollAdapter<UIN_CommonPet> pets = null;
        private UIN_CommonPetTips currTip = null;
        private UIN_CommonPetTips compareTip = null;

        private HeroData heroData = null;
        private PetFilter filter = PetFilter.Default;
        private PetSort sort = PetSort.Default;
        private List<Pet> dataList = new(16);
        private List<Pet> dataCurrList = new(16);
        private long selectedId = -1;
        private int selectedIndex = -1;
        #endregion fields

        #region properties

        protected UIB_UIN_HeroEquipSelectedPetInfo ui { get; set; }
        protected UIMsgDispatcher uiMsgDispatcher => this._msgDispatcher as UIMsgDispatcher;

        #endregion properties

        protected override void BeforeInit()
        {
            ui = new UIB_UIN_HeroEquipSelectedPetInfo();
            ui.InitBinding(this.csObjBind);
        }

        protected override void OnInit()
        {
            this.pets = this.InitLoopScroll<UIN_CommonPet>(this.ui.loopVerticalScrollRect, this.OnPetChanged);
            this.pets.InitUnitSelected(UnitSelectType.ByExButton, this.OnPetSelected);

            this.currTip = this.InitChildNode<UIN_CommonPetTips>(this.ui.petTipsCurrent);
            this.compareTip = this.InitChildNode<UIN_CommonPetTips>(this.ui.petTipsCompare);
        }

        protected override void OnShow()
        {

        }

        protected override void OnHide()
        {
            this.HideTipPanels();
            this.ClearData();
        }

        /// <summary>
        /// 添加UGUI侦听
        /// </summary>
        protected override void AddUGUIListener()
        {
            this.ui.buttonClose.onClick.AddListener(this.OnClickClose);
            this.ui.buttonScreen.onClick.AddListener(this.OnClickScreenFilter);
            this.ui.btnFilterClear.onClick.AddListener(this.OnClickClearScreenFilter);
            this.ui.buttonSort.onClick.AddListener(this.OnClickSort);
            this.ui.buttonClosePetTips.onClick.AddListener(this.HideTipPanels);
        }

        /// <summary>
        /// 添加全局侦听（MsgDispatcher）
        /// </summary>
        protected override void AddMsgListeners()
        {
            this.uiMsgDispatcher.AddListener<PetFilter>(MsgEventType.PetFilter, this.OnMsgFilter);
            this.uiMsgDispatcher.AddListener<PetSort>(MsgEventType.PetSort, this.OnMsgSort);
        }

        protected override void OnDispose()
        {
            this.ClearData();
        }

        #region methonds

        private void OnClickClose()
        {
            var parentUnit = this.GetParentUnit();
            this.Hide();
            parentUnit?.RefreshWhenCloseSelectedPanel();
        }

        private void OnClickScreenFilter()
        {
            this.OpenUI<UIPetListScreen>(UD_PetListScreen.Create(this.filter));
        }

        private void OnClickClearScreenFilter()
        {
            this.RefreshFilterState(PetFilter.Default);
        }

        private void OnClickSort()
        {
            this.OpenUI<UIPetListSort>(UD_PetListSort.Create(this.sort));
        }

        private void OnMsgSort(PetSort sort)
        {
            if (this.sort == sort)
                return;
            this.sort.Sync(sort);
            this.ShowWarehouse(true);
        }

        private void OnMsgFilter(PetFilter filter)
        {
            this.RefreshFilterState(filter);
        }

        private void RefreshFilterState(PetFilter filter)
        {
            if (this.filter == filter)
                return;
            this.filter.Sync(filter);
            this.ShowWarehouse(true);
        }
        private void HideTipPanels()
        {
            this.currTip.Hide();
            this.compareTip.Hide();
        }

        public void Show(HeroData heroData)
        {
            this.SetData(heroData);
            this.Show();
            this.ShowWarehouse();
        }

        private void ClearData()
        {
            this.filter = PetFilter.Default;
            this.sort = PetSort.Default;

            this.heroData = null;
            this.dataList.Clear();
            this.dataCurrList.Clear();
            this.SetListSelectedData(-1);
        }

        private void SetData(HeroData data)
        {
            this.heroData = data;
            this.InitDataList();
            this.SetListSelectedData(data.petId);
        }

        private void InitDataList()
        {
            this.dataList.Clear();
            var list = GameDataCenter.PlayerData.pet.GetPetList();
            this.dataList.AddRange(list);
        }

        private void SetListSelectedData(long selectedId, int selectedIndex = -1)
        {
            this.selectedId = selectedId;
            this.selectedIndex = selectedIndex;
        }

        private void ShowWarehouse(bool isNoSelected = false)
        {
            this.FitlerAndSortDatalist();
            this.ShowListState(isNoSelected);
            this.ShowBtnClearFilter();
        }

        private void FitlerAndSortDatalist()
        {
            this.FitlerDatalist();
            this.SortDataList();
        }

        private void FitlerDatalist()
        {
            this.dataCurrList.Clear();
            this.dataCurrList = PetModule.Instance.LeachList(this.dataList, this.filter, this.dataCurrList);
        }

        private void SortDataList()
        {
            PetModule.Instance.ReorderList(this.dataCurrList, this.sort, this.WearSort);
        }

        private int WearSort(Pet a, Pet b)
        {
            var wearerA = a.currWearer;
            var wearerB = b.currWearer;
            if (wearerA == this.heroData && wearerB != this.heroData)
                return -1;
            if (wearerA != this.heroData && wearerB == this.heroData)
                return 1;
            return 0;
        }

        private void ShowListState(bool isNoSelected)
        {
            int cnt = this.dataCurrList.Count;
            int index = this.GetListSelectedIndex(isNoSelected);
            this.ShowPetList(cnt, index);
            bool isEmpty = cnt == 0;
            this.ShowEmptyList(isEmpty);
        }

        private int GetListSelectedIndex(bool isNoSelected)
        {
            if (isNoSelected)
                return -1;
            int index = this.GetListSelectedIndexBySelectedId();
            if (index == -1)
            {
                index = Math.Min(this.selectedIndex, this.dataCurrList.Count - 1);
            }
            return index;
        }

        private int GetListSelectedIndexBySelectedId()
        {
            int index = -1;
            if (this.selectedId > 0)
            {
                for (int i = 0, cnt = this.dataCurrList.Count; i < cnt; i++)
                {
                    var pet = this.dataCurrList[i];
                    if (pet.id == this.selectedId)
                    {
                        index = i;
                        break;
                    }
                }
            }
            return index;
        }

        private void ShowPetList(int countList, int indexSelected)
        {
            this.pets.RefillCellsAndSelected(countList, indexSelected);
        }

        private void OnPetChanged(UIN_CommonPet item, int index)
        {
            var pet = this.dataCurrList[index];
            item.Show(pet, this.heroData);
            item.SetSelected(this.selectedIndex == index);
        }

        private void OnPetSelected(int index, UIN_CommonPet item)
        {
            UIN_CommonPet last = this.pets.GetTEntity(this.selectedIndex);
            last?.SetSelected(false);
            this.SetListSelectedData(-1);
            this.HideTipPanels();
            if (item == null)
            {
                return;
            }
            Pet pet = this.dataCurrList[index];
            item.SetSelected(true);

            this.SetListSelectedData(pet.id, index);
            this.ShowTipCompare(pet);
            this.ShowTipCurrent(pet);
        }

        private void ShowTipCurrent(Pet pet)
        {
            this.currTip.ShowWear(pet, this.heroData, this.OnClickTipPanelBtn);
        }

        private void OnClickTipPanelBtn(PetTipBtnType btnType, Pet pet)
        {
            switch (btnType)
            {
                case PetTipBtnType.Detail:
                    this.OpenPetDetail(pet);
                    break;
                case PetTipBtnType.Wear:
                    this.DoWear(pet);
                    break;
                case PetTipBtnType.TakeOff:
                    this.SendWear(0).Forget();
                    break;
                default:
                    break;
            }
        }

        private void OpenPetDetail(Pet pet)
        {
            this.OpenUI<UIPetWarehouse>(UD_PetWarehouse.Create(pet));
        }

        private void DoWear(Pet pet)
        {
            var wearer = pet.currWearer;
            long id = pet.id;
            if (wearer != null && wearer != this.heroData)
            {
                string otherHeroName = HeroModule.Instance.GetHeroName(wearer);
                string currHeroName = HeroModule.Instance.GetHeroName(this.heroData);
                NoticeModule.ShowNotice(APIUIHeroInfo.NoticeCid_WearOtherHeroPet, () =>
                {
                    this.SendWear(id).Forget();
                }, null, null, otherHeroName, pet.cfgData.Name, currHeroName);
            }
            else
            {
                this.SendWear(id).Forget();
            }
        }

        // petId = 0 标识脱下
        private async UniTaskVoid SendWear(long petId)
        {
            var result = await HeroModule.NetCore.CS_wearPet(this.heroData.cid, petId);
            if (result.IsSuccess)
            {
                HeroModule.Instance.UpHeroByPOD(result.heroPOD);

                if (this.isActive)
                {
                    this.RefreshAfterResponse(petId);
                }
            }
        }

        private UIN_HeroEquip GetParentUnit()
        {
            return this.parentNode as UIN_HeroEquip;
        }

        private void RefreshAfterResponse(long petId)
        {
            this.SortDataList();
            this.ShowListState(false);
            var parentUnit = this.GetParentUnit();
            parentUnit?.RefreshPet();
        }

        private void ShowTipCompare(Pet pet)
        {
            long curPetId = this.heroData.petId;
            Pet wearPet = null;
            bool isShowCompare = curPetId > 0 && pet.id != curPetId;
            if (isShowCompare)
            {
                isShowCompare = GameDataCenter.PlayerData.pet.TryGetValue(curPetId, out wearPet);
            }

            if (!isShowCompare)
            {
                this.compareTip.Hide();
                return;
            }

            this.compareTip.ShowWear(wearPet, this.heroData);
        }

        private void ShowEmptyList(bool isEmptyList)
        {
            this.ui.emptyScroll.SetActive(isEmptyList);
        }

        private void ShowBtnClearFilter()
        {
            bool isActive = this.filter != PetFilter.Default;
            this.ui.btnFilterClear.SetActive(isActive);
        }
        #endregion methonds
    }
}
